/*
 *  Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 *  This source code is licensed under the MIT license found in the LICENSE
 *  file in the root directory of this source tree.
 *
 */

/*
 *  THIS FILE IS AUTOGENERATED. DO NOT MODIFY IT; ALL CHANGES WILL BE LOST IN
 *  VAIN.
 *
 *  @generated
 */
#pragma once

#include "mcrouter/lib/network/gen/gen-cpp2/Memcache_types.h"
#include "mcrouter/lib/network/gen/gen-cpp2/Memcache.h"

namespace facebook {
namespace memcache {

template <class ServerOnRequest>
class MemcacheServerOnRequestThrift : public thrift::MemcacheSvIf {
 public:
  MemcacheServerOnRequestThrift(
      std::unordered_map<
          folly::EventBase*,
          std::shared_ptr<ServerOnRequest>> serverOnRequestMap)
      : serverOnRequestMap_(std::move(serverOnRequestMap)) {}
  void async_eb_mcAdd(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McAddReply>> callback,
      const facebook::memcache::McAddRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcAppend(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McAppendReply>> callback,
      const facebook::memcache::McAppendRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcCas(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McCasReply>> callback,
      const facebook::memcache::McCasRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcDecr(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McDecrReply>> callback,
      const facebook::memcache::McDecrRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcDelete(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McDeleteReply>> callback,
      const facebook::memcache::McDeleteRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcFlushAll(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McFlushAllReply>> callback,
      const facebook::memcache::McFlushAllRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcFlushRe(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McFlushReReply>> callback,
      const facebook::memcache::McFlushReRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcGat(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McGatReply>> callback,
      const facebook::memcache::McGatRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcGats(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McGatsReply>> callback,
      const facebook::memcache::McGatsRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcGet(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McGetReply>> callback,
      const facebook::memcache::McGetRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcGets(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McGetsReply>> callback,
      const facebook::memcache::McGetsRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcIncr(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McIncrReply>> callback,
      const facebook::memcache::McIncrRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcLeaseGet(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McLeaseGetReply>> callback,
      const facebook::memcache::McLeaseGetRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcLeaseSet(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McLeaseSetReply>> callback,
      const facebook::memcache::McLeaseSetRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcMetaget(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McMetagetReply>> callback,
      const facebook::memcache::McMetagetRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcPrepend(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McPrependReply>> callback,
      const facebook::memcache::McPrependRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcReplace(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McReplaceReply>> callback,
      const facebook::memcache::McReplaceRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcSet(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McSetReply>> callback,
      const facebook::memcache::McSetRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcTouch(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McTouchReply>> callback,
      const facebook::memcache::McTouchRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
  void async_eb_mcVersion(
      std::unique_ptr<apache::thrift::HandlerCallback<facebook::memcache::McVersionReply>> callback,
      const facebook::memcache::McVersionRequest& request) override final {
    onRequestThriftHelper<std::remove_reference_t<decltype(request)>>(
        request, std::move(callback));
  }
 // Return this factory instead of MemcacheAsyncProcessor from getProcessor(),
 // so that we don't use the default statically registered handlers
 class MemcacheAsyncProcessorCustomHandlers
     : public thrift::MemcacheAsyncProcessor {
  public:
   explicit MemcacheAsyncProcessorCustomHandlers(thrift::MemcacheSvIf* svif)
        : MemcacheAsyncProcessor(svif) {
     clearEventHandlers();
   }
 };
 std::unique_ptr<apache::thrift::AsyncProcessor> getProcessor()
     override final {
   return std::make_unique<MemcacheAsyncProcessorCustomHandlers>(this);
 }

 private:
  std::unordered_map<
     folly::EventBase*,
     std::shared_ptr<ServerOnRequest>>
     serverOnRequestMap_;
  static thread_local ServerOnRequest* serverOnRequest_;

  template <class Request>
   void onRequestThriftHelper(
       const Request& request,
       std::unique_ptr<apache::thrift::HandlerCallback<typename Request::reply_type>>
           callback) {
     getServerOnRequest(callback->getEventBase())
         ->onRequestThrift(
             std::move(callback),
             std::move(const_cast<std::remove_const_t<Request>&>(request)));
   }

 // Returns the ServerOnRequest* associated with this evb
  ServerOnRequest* getServerOnRequest(folly::EventBase* evb) {
    if (serverOnRequest_ == nullptr) {
      auto it = serverOnRequestMap_.find(evb);
      CHECK(it != serverOnRequestMap_.end());
      serverOnRequest_ = it->second.get();
    }
    return serverOnRequest_;
  }
};

template <class ServerOnRequest>
thread_local ServerOnRequest*
    MemcacheServerOnRequestThrift<ServerOnRequest>::serverOnRequest_{nullptr};

} // namespace memcache
} // namespace facebook